package com.shuai.frame.server.tcp;

import com.shuai.frame.model.RpcRequest;
import com.shuai.frame.model.RpcResponse;
import com.shuai.frame.protocol.ProtocolMessage;
import com.shuai.frame.protocol.ProtocolMessageDecoder;
import com.shuai.frame.protocol.ProtocolMessageEncoder;
import com.shuai.frame.protocol.ProtocolMessageTypeEnum;
import com.shuai.frame.registry.LocalRegister;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.io.IOException;
import java.lang.reflect.Method;

public class VertTcpHandler implements Handler<NetSocket> {
    @Override
    public void handle(NetSocket netSocket) {
        // 处理连接
        netSocket.handler(new TcpBufferHandlerWrapper((buffer) -> {
            {
                // 接受请求，解码
                ProtocolMessage<RpcRequest> protocolMessage;
                try {
                    protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
                } catch (IOException e) {
                    throw new RuntimeException("协议消息解码错误");
                }
                if (protocolMessage == null) {
                    throw new RuntimeException("协议消息为空");
                }
                RpcRequest rpcRequest = protocolMessage.getBody();

                // 处理请求
                // 构造响应结果对象
                RpcResponse rpcResponse = new RpcResponse();
                try {
                    // 获取要调用的服务实现类，通过反射调用
                    Class<?> implClass = LocalRegister.getService(rpcRequest.getServiceName());
                    Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                    Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                    // 封装返回结果
                    rpcResponse.setData(result);
                    rpcResponse.setDataType(method.getReturnType());
                    rpcResponse.setMessage("ok");
                } catch (Exception e) {
                    e.printStackTrace();
                    rpcResponse.setMessage(e.getMessage());
                    rpcResponse.setException(e);
                }

                // 发送响应，编码
                ProtocolMessage.Header header = protocolMessage.getHeader();
                header.setMessageType((byte) ProtocolMessageTypeEnum.RESPONSE.getCode());
                ProtocolMessage<RpcResponse> responseProtocolMessage = new ProtocolMessage<>(header, rpcResponse);
                try {
                    Buffer encode = ProtocolMessageEncoder.encode(responseProtocolMessage);
                    netSocket.write(encode);
                } catch (IOException e) {
                    throw new RuntimeException("协议消息编码错误");
                }
            }
        }));
    }
}